using System;
using Me.Prettyprint.Hector.Api.Exceptions;
using Thrift;
using Thrift.Protocol;
using Thrift.Server;
using Thrift.Transport;

namespace Me.Prettyprint.Cassandra.Service
{
    /// <summary>
    /// Default implementation handles all the important exceptions that we
    /// know of as of Cassandra 2.x.
    /// </summary>
	public sealed class ExceptionsTranslatorImpl : ExceptionsTranslator
	{
		public HectorException translate(System.Exception original)
		{
			if (original is HectorException)
			{
				return (HectorException) original;
			}
			else if (original is TApplicationException)
			{
				return new HCassandraInternalException(((TApplicationException) original).GetExceptionType(), original.Message);
			}
			else if (original is TTransportException)
			{
                return new HectorTransportException(original);
            }
			else if (original is Org.Apache.Cassandra.Thrift.TimedOutException)
			{
				return new HTimedOutException(original);
			}
			else if (original is Org.Apache.Cassandra.Thrift.InvalidRequestException)
			{
                Org.Apache.Cassandra.Thrift.InvalidRequestException ire = (Org.Apache.Cassandra.Thrift.InvalidRequestException)original;
                string why = ire.Message;
                if (ire.Why != null)
                {
                    why += ". Why: " + ire.Why;
                }
				if (why != null && why.Contains("bootstrap"))
				{
					return new HUnavailableException(original);
				}
				HInvalidRequestException e = new HInvalidRequestException(original);
				e.Why = why;
				return e;
			}
			else if (original is HPoolExhaustedException)
			{
				return (HPoolExhaustedException) original;
			}
			else if (original is HPoolRecoverableException)
			{
				return (HPoolRecoverableException) original;
			}
			else if (original is HInactivePoolException)
			{
				return (HInactivePoolException) original;
			}
			else if (original is TProtocolException)
			{
				return new HInvalidRequestException(original);
			}
			else if (original is Org.Apache.Cassandra.Thrift.NotFoundException)
			{
				return new HNotFoundException(original);
			}
			else if (original is Org.Apache.Cassandra.Thrift.UnavailableException)
			{
				return new HUnavailableException(original);
			}
			else if (original is System.ArgumentOutOfRangeException)
			{
				return new HPoolExhaustedException(original);
			}
			else if (original is System.SystemException)
			{
				return new PoolIllegalStateException(original);
			}
			else
			{
				return new HectorException(original);
			}
		}
	}
}